/*
 ***************************************************************************
 *                                                                         *
 *   This source is free software; you can redistribute it and/or modify   *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This code is distributed in the hope that it will be useful, but      *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   General Public License for more details.                              *
 *                                                                         *
 *   A copy of the GNU General Public License is available on the World    *
 *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
 *   obtain it by writing to the Free Software Foundation,                 *
 *   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        *
 *                                                                         *
 */

import java.awt.Component;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.FloatBuffer;

import javax.imageio.ImageIO;
import javax.media.opengl.*;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;


import java.util.Timer;
import java.util.TimerTask;

import com.sun.opengl.*;
import com.sun.opengl.util.texture.*;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.GLUT;

public class lt_game extends Frame implements GLEventListener, KeyListener {

	public int SCREEN_WIDTH = 800;
	public int SCREEN_HEIGHT = 600;
	public boolean tank_move = false;
	
    private final int NUM_KEYS = 250;
    private boolean[] keys = new boolean[NUM_KEYS];
    private static tanks_base tank1;
    private static tanks_base tank2;
    
    static GLU glu = new GLU(); 
    GLUquadric sky_sphere = glu.gluNewQuadric();
    static Frame frame = new Frame("Liberty Tanks II");    
    static GLCanvas canvas = new GLCanvas();
    GLCapabilities capabilities = new GLCapabilities();
    r_grass render_grass = new r_grass(0.03f);
    private Texture texture;
	private Texture texture_grass;
	private Texture texture_sky;
	private Texture texture_rbeans;
	private Texture texture_wbeans;
    static Texture[] select = new Texture[6];
    public int counter = 2;
    static TVector[] dim_ot_snaryada = new TVector[19];
    private static Animator animator;
    int sleiff_count = 0;
    static GLUT glut = new GLUT();
    static long demostart = System.currentTimeMillis();
    float ElapsedTime;
    public static void main(String[] args) {
 
    	canvas.addGLEventListener(new lt_game());
        frame.add(canvas);
        frame.setSize(800, 600);
        
        frame.setUndecorated(false);
        //frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                exit();
            }
        });
        frame.setVisible(true);
        canvas.requestFocus();
       
        tank1 = new tanks_base();
        tank1.x = 0.5f;
        tank1.y = 0.035f;
        tank1.z = 0.5f;
        //tank1.shoot = new tanks_base();
        tank2 = new tanks_base();
        tank2.x = 0.6f;
        tank2.y = 0.035f;
        tank2.z = 0.5f;
        for (int i=0;i<18;i++) {
            dim_ot_snaryada[i] = new TVector(0.0f);            
        }
        animator = new Animator(canvas);
        animator.start();
    }
    
	Timer timer1 = new Timer();
    TimerTask task = new TimerTask() {
        public void run()
        {

        }
    };
    //timer1.schedule(task, 100 );
    
    public void keyTyped(KeyEvent key)
    {
    }

    public void keyPressed(KeyEvent ke)
    {
      switch (ke.getKeyChar()) {

        case KeyEvent.VK_ESCAPE:
          exit();
          break;
        default :
            if(ke.getKeyCode()<250)
               keys[ke.getKeyCode()]=true;	
            break;
      }
    }

    public void keyReleased(KeyEvent ke)
    {
        if (ke.getKeyCode() < 250) { keys[ke.getKeyCode()] = false; }
    }
    
    public static void exit() {
    	animator.stop();
        frame.dispose();
        
        System.exit(0);
    }
    
    @Override
    public void display(GLAutoDrawable drawable) {
    	final GL gl = drawable.getGL();
        
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glPushMatrix();
        gl.glViewport(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, SCREEN_WIDTH/SCREEN_HEIGHT, 0.1f, 110);
        glu.gluLookAt(tank1.x-0.4*Math.sin(tank1.ang/180*Math.PI),
                      0.1,
                      tank1.z-0.4*Math.cos(tank1.ang/180*Math.PI),
                      tank1.x,
                      0.1,
                      tank1.z,
                      0,
                      1,
                      0);
        
        float ElapsedTime = System.currentTimeMillis() - demostart;        
        
        TVector panzertank = new TVector(tank1.x,0.0f,tank1.z);
        TVector tigrtank = new TVector(tank2.x,0.0f,tank2.z);
        TVector rr = new TVector(0.0f);
        draw_ground(drawable);
        texture_sky.enable();
        texture_sky.bind();
        DrawSkySphere(new TVector(tank1.x,tank1.y,tank1.z),0.05f,drawable);
        
        texture_rbeans.enable();
        texture_rbeans.bind();
        tank1.draw(drawable);
        
        texture_wbeans.enable();
        texture_wbeans.bind();
        tank2.draw(drawable);
        
        gl.glAlphaFunc(GL.GL_GREATER, 0.1f);
        gl.glEnable(GL.GL_ALPHA_TEST);
        
        if (rr.le_DistancePoints(panzertank, tigrtank) < 2.0) {
            //le_RenderBillboard(tigrtank, 0.1f, select[5], drawable);
             select[counter].enable();
             select[counter].bind();
             gl.glPushMatrix();
             gl.glColor3f(1, 0, 0);
             gl.glTranslatef(tigrtank.x,0.05f,tigrtank.z);
             gl.glScalef(0.5f, 0.5f, 0.5f);
             gl.glRotatef(-90, 1, 0, 0);
               gl.glBegin(GL.GL_QUADS);
               gl.glTexCoord2f(0, 0); gl.glVertex3f(-0.1f, 0,-0.1f);
               gl.glTexCoord2f(0, 1); gl.glVertex3f(-0.1f, 0, 0.1f);
               gl.glTexCoord2f(1, 1); gl.glVertex3f(0.1f, 0, 0.1f);
               gl.glTexCoord2f(1, 0); gl.glVertex3f(0.1f, 0,-0.1f);
               gl.glEnd();
             gl.glPopMatrix();
        }
         // le_RenderBillboard(tigrtank, 0.1f, select[counter], drawable);

        if (rr.le_DistancePoints(panzertank, tigrtank) < 2.5){
          //le_RenderBillboard(tigrtank, 0.1f, select[5], drawable);
           select[5].enable();
           select[5].bind();
           gl.glPushMatrix();
           gl.glColor3f(1, 0, 0);
           gl.glTranslatef(tigrtank.x,0.05f,tigrtank.z);
           gl.glScalef(0.5f, 0.5f, 0.5f);
           gl.glRotatef(-90, 1, 0, 0);
             gl.glBegin(GL.GL_QUADS);
             gl.glTexCoord2f(0, 0); gl.glVertex3f(-0.1f, 0,-0.1f);
             gl.glTexCoord2f(0, 1); gl.glVertex3f(-0.1f, 0, 0.1f);
             gl.glTexCoord2f(1, 1); gl.glVertex3f(0.1f, 0, 0.1f);
             gl.glTexCoord2f(1, 0); gl.glVertex3f(0.1f, 0,-0.1f);
             gl.glEnd();
           gl.glPopMatrix();
        }
       
        texture_grass.enable();
        texture_grass.bind();
        gl.glColor3f(255.0f,255.0f,255.0f);
        for (int i=-10;i<10;i++)
            for (int k=-10;k<10;k++) {
       	     TVector trava = new TVector(i, 0.0f, k);
       	     if (rr.le_DistancePoints(panzertank, trava) < 2.0d) {
                  gl.glColor4f(255.0f,255.0f,255.0f,0.0f);
                   if (rr.le_DistancePoints(panzertank, trava) < 2.9d)
                   	gl.glColor4f(255.0f,255.0f,255.0f,0.1f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.8d)
                   	gl.glColor4f(255.0f,255.0f,255.0f,0.2f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.7d)
                   	gl.glColor4f(255.0f,255.0f,255.0f,0.3f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.6d)
                   	gl.glColor4f(255.0f,255.0f,255.0f,0.4f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.5d)
                       gl.glColor4f(255.0f,255.0f,255.0f,0.5f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.4d)
                       gl.glColor4f(255.0f,255.0f,255.0f,0.6f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.3d)
                       gl.glColor4f(255.0f,255.0f,255.0f,0.7f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.2d)
                       gl.glColor4f(255.0f,255.0f,255.0f,0.8f);

                   if (rr.le_DistancePoints(panzertank, trava) < 2.1d)
                       gl.glColor4f(255.0f,255.0f,255.0f,0.9f);

                   if (rr.le_DistancePoints(panzertank, trava) < 1.0d)
                       gl.glColor4f(255.0f,255.0f,255.0f,1.0f);

                render_grass.draw(trava,drawable);                
                render_grass.animated(ElapsedTime);
       	     }
            }
       
        gl.glDisable(GL.GL_ALPHA_TEST);
        
        if (tank1.shoot.enable == true) {
        	tank1.shoot.fly();
        	tank1.shoot.draw_shoot(drawable);
        	
        	  if (Math.sqrt(((tank2.x-tank1.shoot.x)*
                             (tank2.x-tank1.shoot.x))+
                            ((tank2.z-tank1.shoot.z)*
                             (tank2.z-tank1.shoot.z))) < 0.05) {
        		  tank1.shoot.finish();
        		  if (counter <= 0) {
        			  
        		  }else
            		  counter--;
        	  }
        }
        
        
        if (keys['W']) {        	
            if (tank1.tank_speed >= 0.02f)
               tank1.tank_speed = 0.02f;
            else
               tank1.tank_speed += 0.001;
        	tank1.stpf(tank1.tank_speed);
        }else
        {
            if (tank1.tank_speed <= 0)
                tank1.tank_speed = 0;                
             else
                tank1.tank_speed -= 0.001;        
             tank1.stpf(tank1.tank_speed);
        }
        if (keys['A']) tank1.rotl(1.5f);
        if (keys['D']) tank1.rotr(1.5f);
        if (keys['S']) {
        	tank1.tank_speed = 0;
            tank1.stpb(tank1.tank_speed);
        }
        
        if (keys['F']) {  
           tank1.shoot.x = tank1.x;
           tank1.shoot.y = tank1.y;
           tank1.shoot.z = tank1.z;
           tank1.shoot.ang = tank1.ang;
           tank1.shoot.enable = true;
        }
        
        
        gl.glPopMatrix();
    }

	public void dispose(GLAutoDrawable drawable) {
    }

    @Override
    public void init(GLAutoDrawable drawable) {
    	GL gl = drawable.getGL();
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClearDepth(1.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        ((Component) drawable).addKeyListener(this);		
        try {
			texture = TextureIO.newTexture(new File("/home/sniper/workspace/le_tanks/src/ground.bmp"), true);
			texture_grass = TextureIO.newTexture(new File("/home/sniper/workspace/le_tanks/src/trava.tga"), true);
			texture_sky = TextureIO.newTexture(new File("/home/sniper/workspace/le_tanks/src/sky.bmp"), true);
			select[0] = TextureIO.newTexture(new File("decals/select_0.tga"), true);
			select[1] = TextureIO.newTexture(new File("decals/select_1.tga"), true);
			select[2] = TextureIO.newTexture(new File("decals/select_2.tga"), true);
			select[3] = TextureIO.newTexture(new File("decals/select_3.tga"), true);
			select[4] = TextureIO.newTexture(new File("decals/select_4.tga"), true);
			select[5] = TextureIO.newTexture(new File("decals/select_5.tga"), true);
			texture_rbeans = TextureIO.newTexture(new File("decals/r_beans.tga"), true);
			texture_wbeans = TextureIO.newTexture(new File("decals/w_beans.tga"), true);			
			
		} catch (GLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }

	@Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
    	
        GL gl = drawable.getGL();
        if (height <= 0) {
            height = 1;
        }
        float h = (float) width / (float) height;
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(50.0f, h, 1.0, 100.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    	
    }
    
    private void DrawSkySphere(TVector position, float ang_rot, GLAutoDrawable drawable){
    	GL gl = drawable.getGL();
        gl.glPushMatrix();
        glu.gluQuadricTexture(sky_sphere, true);
        gl.glTranslated(position.x,position.y,position.z);
        gl.glRotatef(90,1,0,0);
        gl.glRotatef(ang_rot,0,0,1);
        glu.gluSphere(sky_sphere, 30,28,28);
        gl.glPopMatrix();
    }
	
	private void draw_ground(GLAutoDrawable drawable) {
		
    	GL gl = drawable.getGL();
    	texture.enable();
        texture.bind();
        gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
        TextureCoords coords = texture.getImageTexCoords();
        
        gl.glPushMatrix();
        gl.glBegin(GL.GL_QUADS);
        gl.glNormal3d(0.0, 1.0, 0.0);
        gl.glTexCoord2f(coords.left(), coords.bottom()); gl.glVertex3f(-10, 0,-10);
        gl.glTexCoord2f(coords.left(), coords.top()); gl.glVertex3f(-10, 0, 10);
        gl.glTexCoord2f(coords.right(), coords.top()); gl.glVertex3f(10, 0, 10);
        gl.glTexCoord2f(coords.right(), coords.bottom()); gl.glVertex3f(10, 0,-10);
        gl.glEnd();
        gl.glPopMatrix();
        
    }

}
